package com.jdrx.ocp.service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Maps;
import com.jdrx.ocp.beans.constans.EDeleteFlag;
import com.jdrx.ocp.beans.constans.EUseAble;
import com.jdrx.ocp.beans.constans.ServiceGroupEnum;
import com.jdrx.ocp.beans.constans.ServiceTypeEnum;
import com.jdrx.ocp.beans.dto.platform.*;
import com.jdrx.ocp.beans.entity.PlatformExtendPO;
import com.jdrx.ocp.beans.entity.PlatformPO;
import com.jdrx.ocp.beans.entity.util.ExceptionMessageFilter;
import com.jdrx.ocp.beans.vo.PlatformApiVO;
import com.jdrx.ocp.beans.vo.QueryPlatformExtendVO;
import com.jdrx.ocp.beans.vo.QueryPlatformPrefixVO;
import com.jdrx.ocp.beans.vo.QueryPlatformVO;
import com.jdrx.ocp.config.DesConfig;
import com.jdrx.ocp.dao.PlatformDAO;
import com.jdrx.ocp.dao.PlatformExtendDAO;
import com.jdrx.ocp.utils.DesUtil;
import com.jdrx.platform.commons.rest.exception.BizException;
import com.jdrx.platform.jdbc.beans.vo.PageVO;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName:SysPlatformService
 * @Description:平台管理模块接口
 * @author: yangfang
 * @date: 2018/11/19 13:41
 */
@Service
public class PlatformService {
    private static final Logger logger = LoggerFactory.getLogger(PlatformService.class);
    @Autowired
    private PlatformDAO platformDAO;

    @Autowired
    private PlatformExtendDAO platformExtendDAO;

    @Autowired
    private DesConfig desConfig;

    @Autowired
    private PlatformApiService platformApiService;

    /**
     * 初始化搜索条件
     *
     * @param dto
     * @param query
     * @return
     */
    private Map <String, Object> initQueryParams(QueryPlatformDTO dto, Map <String, Object> query) throws BizException {
        query.put("name", StringUtils.isBlank(dto.getName()) ? null : dto.getName());
        query.put("prefix", StringUtils.isBlank(dto.getPrefix()) ? null : dto.getPrefix());
        query.put("serviceType", dto.getServiceType() == null ? null : dto.getServiceType());
        return query;
    }

    /**
     * 分页查询平台信息
     *
     * @param dto
     * @return
     */
    public PageVO queryPlatformByPage(QueryPlatformDTO dto) throws BizException {
        try {
            Map <String, Object> query = new HashMap <String, Object>();
            initQueryParams(dto, query);
            Page <PlatformPO> page = PageHelper.startPage(dto.getPageNum(), dto.getPageSize(), "id DESC");
            platformDAO.listBy(query);


            if (ServiceTypeEnum.OLD_SERVICE.getType().equals(dto.getServiceType())) {
                /* 旧系统*/
                PageVO <QueryPlatformExtendVO> pageVO = new PageVO <QueryPlatformExtendVO>(page);
                List <PlatformPO> platformPOList = page.getResult();
                if (CollectionUtils.isEmpty(platformPOList)) {
                    return pageVO;
                }

                // 提取平台id
                List <Long> platformIds = platformPOList.stream()
                        .map(platformPO -> platformPO.getId())
                        .collect(Collectors.toList());
                query.clear();
                query.put("ids", platformIds);
                // 查询平台扩展信息
                List <PlatformExtendPO> platformExtendPOList = platformExtendDAO.listBy(query);

                pageVO.setData(generateQueryPlatformExtendVO(platformPOList, platformExtendPOList));
                return pageVO;
            }

            // 应用服务
            PageVO <QueryPlatformVO> pageVO = new PageVO <QueryPlatformVO>(page);
            pageVO.setData(generateQueryPlatformVO(page.getResult()));
            return pageVO;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BizException("获取数据失败！");
        }
    }

    /**
     * 获取平台内部服务
     * @return
     */
    public List<QueryPlatformVO> queryPlatformByInterior(){
        Map<String,Object> map = Maps.newHashMap();
        map.put("serviceFlag",1);
        List<PlatformPO> list = platformDAO.listBy(map);
        try {
            return generateQueryPlatformVO(list);
        } catch (BizException e) {
            e.printStackTrace();
            logger.error("获取内部服务信息失败！");
            return null;
        }
    }

    /**
     * 分页查询平台管理VO封装
     *
     * @param datas
     * @return
     * @throws BizException
     */
    private List <QueryPlatformVO> generateQueryPlatformVO(List <PlatformPO> datas) throws BizException {
        try {
            List <QueryPlatformVO> voList = new ArrayList <QueryPlatformVO>();
            if (CollectionUtils.isEmpty(datas)) {
                return voList;
            }
            for (PlatformPO t : datas) {
                QueryPlatformVO vo = new QueryPlatformVO();
                BeanUtils.copyProperties(t, vo);
                vo.setServiceGroupName(serviceGroupName(vo.getServiceGroup()));
                voList.add(vo);
            }
            return voList;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BizException("获取数据失败！");
        }
    }

    /**
     * 分页查询平台管理VO封装(旧系统)
     *
     * @param platformPOList
     * @param platformExtendPOList
     * @return
     * @throws BizException
     */
    private List <QueryPlatformExtendVO> generateQueryPlatformExtendVO(List <PlatformPO> platformPOList, List <PlatformExtendPO> platformExtendPOList) throws BizException {
        try {
            List <QueryPlatformExtendVO> voList = new ArrayList <QueryPlatformExtendVO>();
            Map<Long,List<PlatformExtendPO>> platformExtendPOMap=platformExtendPOList.stream()
                    .collect(Collectors.groupingBy(PlatformExtendPO::getPlatformId));
            for (PlatformPO t : platformPOList) {
                QueryPlatformExtendVO vo = new QueryPlatformExtendVO();
                BeanUtils.copyProperties(t, vo);
                PlatformExtendPO platformExtendPO=platformExtendPOMap.get(t.getId()).get(0);
                BeanUtils.copyProperties(platformExtendPO, vo);
                vo.setServiceGroupName(serviceGroupName(vo.getServiceGroup()));
                voList.add(vo);
            }
            return voList;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BizException("获取数据失败！");
        }
    }


    /**
     * 创建平台信息
     *
     * @param t
     * @param userId
     * @throws BizException
     */
    @Transactional(rollbackFor = Exception.class)
    public PlatformPO createPlatform(CreatePlatformDTO t, Long userId,Integer type) throws BizException {
        try {
            if(checkPlatformIsExist(t.getPrefix(),t.getName())){
                throw new BizException("该平台已经存在");
            }

            PlatformPO po = new PlatformPO();
            BeanUtils.copyProperties(t, po);
            po.setDelFlag(EDeleteFlag.NORMAL.getKey());
            po.setCreateBy(userId);
            po.setVerifyKey(DesUtil.encrypt(po.getPrefix(), desConfig.getDefaultKey()));
            if(ServiceTypeEnum.NEW_SERVICE.getType().equals(type)){
                po.setServiceType(ServiceTypeEnum.NEW_SERVICE.getType());
            }else{
                po.setServiceType(ServiceTypeEnum.OLD_SERVICE.getType());
            }
            if (platformDAO.insert(po) <= 0) {
                throw new BizException("创建平台信息失败");
            }
            return po;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BizException(ExceptionMessageFilter.filter(e.getMessage()));
        }
    }


    /**
     * 创建平台信息(旧系统配置)
     *
     * @param t
     * @param userId
     * @throws BizException
     */
    @Transactional(rollbackFor = Exception.class)
    public void createPlatformExtend(CreatePlatformExtendDTO t, Long userId) throws BizException {
        try {
            if(checkPlatformIsExist(t.getPrefix(),t.getName())){
                throw new BizException("该平台已经存在");
            }

            // 添加平台信息
            CreatePlatformDTO platformDTO=new CreatePlatformDTO();
            BeanUtils.copyProperties(t, platformDTO);
            PlatformPO platformPO=createPlatform(platformDTO,userId,ServiceTypeEnum.OLD_SERVICE.getType());

            // 添加扩展信息
            PlatformExtendPO platformExtendPO = new PlatformExtendPO();
            BeanUtils.copyProperties(t, platformExtendPO);
            platformExtendPO.setPlatformId(platformPO.getId());
            if (platformExtendDAO.insert(platformExtendPO) <= 0) {
                throw new BizException("创建平台信息失败");
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BizException(ExceptionMessageFilter.filter(e.getMessage()));
        }
    }


    /**
     * 检查平台信息是否存在
     * @param prefix
     * @param name
     * @return
     */
    private Boolean checkPlatformIsExist(String prefix,String name){
        Map <String, Object> query = new HashMap <String, Object>();
        query.put("prefix", prefix);
        query.put("name", name);

        List <PlatformPO> datas = platformDAO.listBy(query);
        if (!CollectionUtils.isEmpty(datas) && datas.size() > 0) {
            return true;
        }

        return false;
    }

    /**
     * 修改平台信息
     *
     * @param dto
     * @param userId
     * @throws BizException
     */
    @Transactional(rollbackFor = Exception.class)
    public void updatePlatform(UpdatePlatformDTO dto, Long userId) throws BizException {
        try {
            PlatformPO old = platformDAO.getById(Long.valueOf(dto.getId()));
            if (old == null) {
                throw new BizException("该平台不存在或者已经被删除");
            }

            PlatformPO po = new PlatformPO();
            BeanUtils.copyProperties(dto, po);
            po.setUpdateBy(userId);
            if (platformDAO.update(po) <= 0) {
                throw new BizException("修改平台信息失败");
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BizException(ExceptionMessageFilter.filter(e.getMessage()));
        }
    }


    /**
     * 修改平台信息(旧系统配置)
     *
     * @author : zhongsen
     * @date : 2019/2/12 15:19
     */
    @Transactional(rollbackFor = Exception.class)
    public void updatePlatformExtend(UpdatePlatformExtendDTO dto, Long userId) throws BizException {
        try {
            // 修改平台信息
            UpdatePlatformDTO PlatformPO=new UpdatePlatformDTO();
            BeanUtils.copyProperties(dto, PlatformPO);
            updatePlatform(PlatformPO,userId);

            // 扩展信息修改
            PlatformExtendPO platformExtendPO = platformExtendDAO.getById(dto.getId());
            if (platformExtendPO == null) {
                throw new BizException("该平台不存在或者已经被删除");
            }
            PlatformExtendPO platformExtendPO1=new PlatformExtendPO();
            BeanUtils.copyProperties(dto, platformExtendPO1);
            platformExtendPO1.setPlatformId(dto.getId());
            if (platformExtendDAO.update(platformExtendPO1) <= 0) {
                throw new BizException("修改平台信息失败");
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BizException(ExceptionMessageFilter.filter(e.getMessage()));
        }
    }

    /**
     * 删除平台信息
     *
     * @param id
     * @param userId
     * @throws BizException
     */
    @Transactional(rollbackFor = Exception.class)
    public void deletePlatform(Long id, Long userId) throws BizException {
        try {
            PlatformPO po = new PlatformPO();
            po.setId(id);
            po.setDelFlag(EDeleteFlag.DELETE.getKey());
            po.setUpdateBy(userId);
            int num = platformDAO.deleteByCondition(po);
            if (num <= 0) {
                throw new BizException("删除平台信息失败");
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BizException(ExceptionMessageFilter.filter(e.getMessage()));
        }
    }

    /**
     * 启用或停用
     *
     * @param updateUseableDTO
     * @param userId
     * @throws BizException
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUseable(UpdateUseableDTO updateUseableDTO, Long userId) throws BizException {
        try {
            PlatformPO po = new PlatformPO();
            po.setId(updateUseableDTO.getId());
            po.setUseable(updateUseableDTO.getUseable());
            po.setUpdateBy(userId);
            if (platformDAO.updateUseable(po) <= 0) {
                throw new BizException("启停操作失败");
            }
            return true;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BizException(ExceptionMessageFilter.filter(e.getMessage()));
        }
    }

    /**
     * 启用应用，用于saas平台创建租户时初始化可使用的应用
     * @param list
     */
    public void enableApp(List<String> list){
        //先禁用所有应用然后再重新开启授权应用
        platformDAO.disableApp();
        if(!CollectionUtils.isEmpty(list)) {
            platformDAO.enableApp(list);
        }
    }

    /**
     * 获取平台以及前缀数据
     *
     * @param queryPlatformPrefixDTO
     * @return
     * @throws BizException
     */
    public List <QueryPlatformPrefixVO> queryPlatformPrefix(QueryPlatformPrefixDTO queryPlatformPrefixDTO) throws BizException {
        try {
            Map <String, Object> query = new HashMap <String, Object>(4);
            query.put("name", queryPlatformPrefixDTO.getName());
            query.put("prefix", queryPlatformPrefixDTO.getPrefix());
            List <PlatformPO> list = platformDAO.listBy(query);
            List <QueryPlatformPrefixVO> voList = new ArrayList <>();
            list.stream().forEach(item -> {
                QueryPlatformPrefixVO queryPlatformPrefixVO = new QueryPlatformPrefixVO();
                BeanUtils.copyProperties(item, queryPlatformPrefixVO);
                voList.add(queryPlatformPrefixVO);
            });
            return voList;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BizException("获取数据失败！");
        }
    }

    public List <PlatformPO> getPlatform() throws BizException {
        try {
            Map <String, Object> map = new HashMap <>(3);
            map.put("delFlag", EDeleteFlag.NORMAL.getKey());
            map.put("useable", Integer.valueOf(EUseAble.ENABLE.getKey()));
            return platformDAO.listBy(map);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BizException("获取数据失败！");
        }
    }

    public String serviceGroupName(Integer serviceGroup) {
        switch (serviceGroup) {
//            case 0:
//                return ServiceGroupEnum.MANAGEMENT_COCKPIT.getDesc();
            case 1:
                return ServiceGroupEnum.SMART_PRODUCTION.getDesc();
            case 2:
                return ServiceGroupEnum.SMART_OPERATION.getDesc();
            case 3:
                return ServiceGroupEnum.PLATFORM_MANAGEMENT.getDesc();
            default:
                return "";
        }
    }

    /**
     * 获取所有的可用服务
     * @return
     * @throws BizException
     */
    public List<PlatformApiVO> queryListByEnable(PlatformDTO platformDTO,String token) throws BizException {
        try{
            Map<String,Object> map = new HashMap<>(2);
            map.put("useable",EUseAble.ENABLE.getKey());
            map.put("name",platformDTO.getName());
            map.put("prefix",platformDTO.getPrefix());
            List<PlatformPO> list = platformDAO.listBy(map);
            //接口中心的服务统计
            List<Map<String,Object>> apiCenterService = platformApiService.getServices(token,new ExportPlatformApiDTO());
            List<PlatformApiVO> reList = new ArrayList<>();
            list.forEach(item->{
                PlatformApiVO platformApiVO = new PlatformApiVO();
                BeanUtils.copyProperties(item,platformApiVO);
                for(Map<String,Object> api : apiCenterService){
                    if(String.valueOf(api.get("servicePrefix")).equals(platformApiVO.getPrefix())){
                        platformApiVO.setApiNumber(Integer.valueOf(String.valueOf(api.get("apiNumber"))));
                        platformApiVO.setModelNumber(Integer.valueOf(String.valueOf(api.get("modelNumber"))));
                        platformApiVO.setEnable(Integer.valueOf(String.valueOf(api.get("enable"))));
                        platformApiVO.setDisable(Integer.valueOf(String.valueOf(api.get("disable"))));
                        break;
                    }
                }
                reList.add(platformApiVO);
            });
            return reList;
        }catch (Exception e){
            throw new BizException("获取服务失败！");
        }
    }

    /**
     * 获取服务统计以及接口统计信息
     * @param token
     * @return
     * @throws BizException
     */
    public Map<String, Object> queryServiceApiCount(String token) throws BizException {
        try{
            Map<String,Object> resultMap = new HashMap<>();
            //服务统计
            Map<String,Object> map = new HashMap<>(2);
            map.put("useable",0);
            List<PlatformPO> list = platformDAO.listBy(map);
            resultMap.put("serviceNum",list.size());
            resultMap.put("inServiceNum",list.stream().filter(item->item.getServiceFlag() == 1).count());
            resultMap.put("outServiceNum",list.stream().filter(item->item.getServiceFlag() != 1).count());
            //接口统计
            List<String> prefixs = new ArrayList<>();
            for (PlatformPO po : list){
                prefixs.add(po.getPrefix());
            }
            Map<String,Object> apiMap = platformApiService.getStatisticNum(token,prefixs);
            if(apiMap != null){
                resultMap.put("modelNum",apiMap.get("modelNum"));
                resultMap.put("enableNum",apiMap.get("enableNum"));
                resultMap.put("apiNum",apiMap.get("apiNum"));
                resultMap.put("disableNum",apiMap.get("disableNum"));
            }else{
                resultMap.put("modelNum",0);
                resultMap.put("enableNum",0);
                resultMap.put("apiNum",0);
                resultMap.put("disableNum",0);
            }
            return resultMap;
        }catch (Exception e){
            logger.error(e.getMessage());
            throw new BizException("获取统计信息失败！");
        }
    }

    public PlatformExtendPO getPlatformExtend(String prefix) throws BizException {
        try{
            PlatformPO platformPO = platformDAO.getByPrefix(prefix);
            if(platformPO == null){
                throw new BizException("获取服务信息失败！");
            }
            PlatformExtendPO platformExtendPO = platformExtendDAO.getById(platformPO.getId());
            if(platformExtendPO == null){
                throw new BizException("获取服务扩展信息失败！");
            }
            return platformExtendPO;
        }catch (Exception e){
            throw new BizException("获取服务扩展信息失败！");
        }
    }

}
